home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / tcsh / dist / tc.sig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-21  |  7.8 KB  |  381 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.01/RCS/tc.sig.c,v 3.6 1991/11/11 01:56:34 christos Exp $ */
  2. /*
  3.  * sh.sig.c: Signal routine emulations
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "sh.h"
  38.  
  39. RCSID("$Id: tc.sig.c,v 3.6 1991/11/11 01:56:34 christos Exp $")
  40.  
  41. #include "tc.wait.h"
  42.  
  43. #ifndef BSDSIGS
  44.  
  45. /* this stack is used to queue signals
  46.  * we can handle up to MAX_CHLD outstanding children now;
  47.  */
  48. #define MAX_CHLD 50
  49. static struct mysigstack {
  50.     int     s_w;        /* wait report             */
  51.     int     s_errno;        /* errno returned;         */
  52.     pid_t   s_pid;        /* pid returned             */
  53. }       stk[MAX_CHLD];
  54. static int stk_ptr = -1;
  55.  
  56.  
  57. #ifdef UNRELSIGS
  58. /* queue child signals
  59.  */
  60. static sigret_t
  61. sig_ch_queue()
  62. {
  63. #ifdef JOBDEBUG
  64.     xprintf("queue SIGCHLD\n");
  65.     flush();
  66. #endif /* JOBDEBUG */
  67.     stk_ptr++;
  68.     stk[stk_ptr].s_pid = (pid_t) wait(&stk[stk_ptr].s_w);
  69.     stk[stk_ptr].s_errno = errno;
  70.     (void) signal(SIGCHLD, sig_ch_queue);
  71. #ifndef SIGVOID
  72.     return(0);
  73. #endif /* SIGVOID */
  74. }
  75.  
  76. /* process all awaiting child signals
  77.  */
  78. static sigret_t
  79. sig_ch_rel()
  80. {
  81.     while (stk_ptr > -1)
  82.     pchild(SIGCHLD);
  83. #ifdef JOBDEBUG
  84.     xprintf("signal(SIGCHLD, pchild);\n");
  85. #endif /* JOBDEBUG */
  86.     (void) signal(SIGCHLD, pchild);
  87. #ifndef SIGVOID
  88.     return(0);
  89. #endif /* SIGVOID */
  90. }
  91.  
  92. /* libc.a contains these functions in SVID >= 3. */
  93. sigret_t
  94. (*sigset(a, b)) ()
  95.     int     a;
  96.     sigret_t  (*b) __P((int));
  97. {
  98.     return (signal(a, b));
  99. }
  100.  
  101. /* release signal
  102.  *    release all queued signals and
  103.  *    set the default signal handler
  104.  */
  105. void
  106. sigrelse(what)
  107.     int     what;
  108. {
  109.     if (what == SIGCHLD)
  110.     sig_ch_rel();
  111.  
  112. #ifdef notdef    /* XXX: Should not need that when compiled with SVID=1 */
  113. # ifdef UNIXPC    
  114.     if (what == SIGINT)
  115.         (void)signal(SIGINT, pintr);
  116. # endif
  117. #endif
  118. }
  119.  
  120. /* hold signal
  121.  * only works with child and interrupt
  122.  */
  123. void
  124. sighold(what)
  125.     int     what;
  126. {
  127.     if (what == SIGCHLD)
  128.     (void) signal(SIGCHLD, sig_ch_queue);
  129.  
  130. #ifdef notdef    /* XXX: Should not need that when compiled with SVID=1 */
  131. # ifdef UNIXPC    
  132.     if (what == SIGINT)
  133.         (void)signal(SIGINT, SIG_IGN);
  134. # endif
  135. #endif
  136. }
  137.  
  138. /* ignore signal
  139.  */
  140. void
  141. sigignore(a)
  142.     int     a;
  143. {
  144.     (void) signal(a, SIG_IGN);
  145. }
  146.  
  147. /* atomically release one signal
  148.  */
  149. void
  150. sigpause(what)
  151.     int     what;
  152. {
  153. #ifdef notdef
  154.     if (what == SIGCHLD) {
  155.     if (stk_ptr > -1) {
  156.         pchild(SIGCHLD);
  157.     }
  158.     else {
  159.         (void) sleep(1);
  160.     }
  161.     }
  162. #endif
  163.     /* From: Jim Mattson <mattson%cs@ucsd.edu> */
  164.     if (what == SIGCHLD)
  165.     pchild(SIGCHLD);
  166.  
  167. }
  168.  
  169. #endif /* UNRELSIGS */
  170.  
  171. #ifdef SXA
  172. /*
  173.  * SX/A is SVID3 but does not have sys5-sigpause().
  174.  * I've heard that sigpause() is not defined in SVID3.
  175.  */
  176. /* This is not need if you make tcsh by BSD option's cc. */
  177. void
  178. sigpause(what)
  179. {
  180.     if (what == SIGCHLD) {
  181.     bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
  182.     }
  183.     else if (what == 0) {
  184.     pause();
  185.     }
  186.     else {
  187.     xprintf("sigpause(%d)\n", what);
  188.     pause();
  189.     }
  190. }
  191.  
  192. #endif /* SXA */
  193.  
  194. /* return either awaiting processes or do a wait now
  195.  */
  196. pid_t
  197. ourwait(w)
  198.     int    *w;
  199. {
  200.     pid_t pid;
  201.  
  202. #ifdef JOBDEBUG
  203.     xprintf("our wait %d\n", stk_ptr);
  204.     flush();
  205. #endif /* JOBDEBUG */
  206.  
  207.     if (stk_ptr == -1) {
  208.     /* stack empty return signal from stack */
  209.     pid = (pid_t) wait(w);
  210. #ifdef JOBDEBUG
  211.     xprintf("signal(SIGCHLD, pchild);\n");
  212. #endif /* JOBDEBUG */
  213.     (void) signal(SIGCHLD, pchild);
  214.     return (pid);
  215.     }
  216.     else {
  217.     /* return signal from stack */
  218.     errno = stk[stk_ptr].s_errno;
  219.     *w = stk[stk_ptr].s_w;
  220.     stk_ptr--;
  221.     return (stk[stk_ptr + 1].s_pid);
  222.     }
  223. } /* end ourwait */
  224.  
  225. #endif /* BSDSIGS */
  226.  
  227. #ifdef NEEDsignal
  228. /* turn into bsd signals */
  229. sigret_t(*
  230.      xsignal(s, a)) ()
  231.     int     s;
  232.     sigret_t (*a) __P((int));
  233. {
  234.     sigvec_t osv, sv;
  235.  
  236.     (void) mysigvec(s, NULL, &osv);
  237.     sv = osv;
  238.     sv.sv_handler = a;
  239. #ifdef SIG_STK
  240.     sv.sv_onstack = SIG_STK;
  241. #endif
  242. #ifdef SV_BSDSIG
  243.     sv.sv_flags = SV_BSDSIG;
  244. #endif
  245.  
  246.     if (mysigvec(s, &sv, NULL) < 0)
  247.     return (BADSIG);
  248.     return (osv.sv_handler);
  249. }
  250.  
  251. #endif /* NEEDsignal */
  252.  
  253. #ifdef _SEQUENT_
  254. /*
  255.  * Support for signals.
  256.  */
  257.  
  258. extern int errno;
  259.  
  260. /* Set and test a bit.  Bits numbered 1 to 32 */
  261.  
  262. #define SETBIT(x, y)    x |= sigmask(y)
  263. #define ISSET(x, y)    ((x & sigmask(y)) != 0)
  264.  
  265. #ifdef DEBUG
  266. # define SHOW_SIGNALS    1    /* to assist in debugging signals */
  267. #endif
  268.  
  269. #ifdef SHOW_SIGNALS
  270. char   *show_sig_mask();
  271. #endif
  272.  
  273. int     debug_signals = 0;
  274.  
  275. /*
  276.  * igsetmask(mask)
  277.  *
  278.  * Set a new signal mask.  Return old mask.
  279.  */
  280. sigmask_t
  281. sigsetmask(mask)
  282.     sigmask_t     mask;
  283. {
  284.     sigset_t set, oset;
  285.     int     m;
  286.     register int i;
  287.  
  288.     sigemptyset(&set);
  289.     sigemptyset(&oset);
  290.  
  291.     for (i = 1; i <= MAXSIG; i++)
  292.     if (ISSET(mask, i))
  293.         sigaddset(&set, i);
  294.  
  295.     if (sigprocmask(SIG_SETMASK, &set, &oset))
  296.     xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
  297.         mask, errno);
  298.  
  299.     m = 0;
  300.     for (i = 1; i < MAXSIG; i++)
  301.     if (sigismember(&oset, i))
  302.         SETBIT(m, i);
  303.  
  304.     return (m);
  305. }
  306.  
  307. /*
  308.  * sigblock(mask)
  309.  *
  310.  * Add "mask" set of signals to the present signal mask.
  311.  * Return old mask.
  312.  */
  313. sigmask_t
  314. sigblock(mask)
  315.     sigmask_t     mask;
  316. {
  317.     sigset_t set, oset;
  318.     int     m;
  319.     register int i;
  320.  
  321.     set = 0;
  322.     oset = 0;
  323.  
  324.     /* Get present set of signals. */
  325.     if (sigprocmask(SIG_SETMASK, NULL, &set))
  326.     xprintf("sigblock(0x%x) - sigprocmask failed, errno %d",
  327.         mask, errno);
  328.  
  329.     /* Add in signals from mask. */
  330.     for (i = 1; i <= MAXSIG; i++)
  331.     if (ISSET(mask, i))
  332.         sigaddset(&set, i);
  333.  
  334.     sigprocmask(SIG_SETMASK, &set, &oset);
  335.  
  336.     /* Return old mask to user. */
  337.     m = 0;
  338.     for (i = 1; i < MAXSIG; i++)
  339.     if (sigismember(&oset, i))
  340.         SETBIT(m, i);
  341.  
  342.     return (m);
  343. }
  344.  
  345.  
  346. /*
  347.  * bsd_sigpause(mask)
  348.  *
  349.  * Set new signal mask and wait for signal;
  350.  * Old mask is restored on signal.
  351.  */
  352. void
  353. bsd_sigpause(mask)
  354.     sigmask_t     mask;
  355. {
  356.     sigset_t set;
  357.     register int i;
  358.  
  359.     sigemptyset(&set);
  360.  
  361.     for (i = 1; i <= MAXSIG; i++)
  362.     if (ISSET(mask, i))
  363.         sigaddset(&set, i);
  364.     sigsuspend(&set);
  365. }
  366. #endif /* _SEQUENT_ */
  367.  
  368.  
  369. #ifdef SIGSYNCH
  370. static long Synch_Cnt = 0;
  371.  
  372. sigret_t
  373. synch_handler(sno)
  374. int sno;
  375. {
  376.     if (sno != SIGSYNCH)
  377.     abort();
  378.     Synch_Cnt++;
  379. }
  380. #endif /* SIGSYNCH */
  381.